package cn.edu.nuaa.aadl2.generatorC.template
import static extension cn.edu.nuaa.aadl2.generatorC.utils.Tools.*
import static extension cn.edu.nuaa.aadl2.generatorC.utils.StringUtils.*
import static extension cn.edu.nuaa.aadl2.generatorC.utils.PropertyParser.*
import org.osate.ba.aadlba.impl.*
import org.osate.ba.aadlba.*
import org.osate.ba.utils.*
import org.osate.aadl2.Subcomponent
import org.osate.aadl2.ThreadSubcomponent
import org.osate.aadl2.Element
import org.osate.aadl2.impl.DataImplementationImpl
import org.osate.aadl2.impl.DataTypeImpl
import org.eclipse.emf.common.util.EList
import org.osate.ba.aadlba.DataSubcomponentHolder

class BaAnnexTemplate {
	
	def static baVariable(BehaviorAnnexImpl ba)'''
	«FOR Element sub :ba.children»
	«switch sub{
			BehaviorVariable : '''
			«sub.variableTemplate»
			'''
	}»
	«ENDFOR»	
	enum State{«ba.stateEnum.toString.clearspace»};
	'''

	def static baMain(BehaviorAnnexImpl ba,Boolean flag)'''
	«ba.getInitialStateEx.toString.clearspace» 
	«ba.getFinalStateEx.toString.clearspace»
	enum State current_state = initialState;
	while(1){
		switch(current_state){
		«FOR state :ba.states»
			«state.stateTemplate.toString»
				«IF state.isFinal»
					printf("finish!");
					«IF flag»
						return;
					«ELSE»
						current_state=initialState ;
					«ENDIF»
				«ELSE»
				break;
				«ENDIF»
			«ENDFOR»
		default:
			break;	
		}
	}
	
	'''
	
	
	def static stateEnum(BehaviorAnnexImpl ba)'''
	«FOR Element sub :ba.children»
	«switch sub{
		BehaviorState:'''
		«IF sub.isInitial»«sub.name»«ELSE» , «sub.name»«ENDIF»
		'''}»
	«ENDFOR»
	'''	
	
	
	def static variableTemplate(BehaviorVariable bv){'''
	«var BV= bv.dataClassifier»
	«switch BV{	
					DataImplementationImpl:
							'''«BV.name.convertNo2Low»  «bv.name»;'''
					DataTypeImpl:
							'''«BV.name.convertNo2Low»  «bv.name»;'''
				}»
	'''
	}											
	
	def static stateTemplate(BehaviorState bs)'''
	case «bs.name»:
	«FOR transition:AadlBaVisitors.getTransitionWhereSrc(bs)»
	«IF bs==transition.getSourceState»
		«transition.transitionTemplate»
	«ENDIF»
	«ENDFOR»
	'''	
	
	def static transitionTemplate(BehaviorTransition bt)'''
	if( «bt.condition.conditionsTemplate.toString.clearspace» ){
		«bt.actionBlock.actionblockTemplate»
		current_state = «bt.destinationState.name»;
	}
	'''	
	
	
	def static conditionsTemplate(BehaviorCondition  bc)'''
		«IF bc!==null»
		«var BC=bc»
		«var tag=false»
		«switch BC{
			ValueExpressionImpl:'''
			«IF BC.children.size==0»
			«ELSEIF BC.isSetLogicalOperators»
				«var logic=BC.logicalOperators»
				«var logic_index=logic.length»
				«var index=0»
				«FOR Relation condition :BC.getRelations()»
					«IF condition.firstExpression.terms.get(0).getFactors.get(0).getUnaryBooleanOperator.toString=="!"»
						!(«condition.conditionTemplate»)
					«ELSE»
						(«condition.conditionTemplate»)«IF BC.isSetLogicalOperators&&index<logic_index»«logic.get(index++).translateLogOperator»«ENDIF»
					«ENDIF»
				«ENDFOR»
			«ELSE»
				«FOR Relation condition :BC.getRelations()»
					«IF condition.firstExpression.terms.get(0).getFactors.get(0).getUnaryBooleanOperator.toString=="!"»
						!(«condition.conditionTemplate»)
					«ELSE»
						(«condition.conditionTemplate»)
					«ENDIF»
				«ENDFOR»
			«ENDIF»	
			'''
			DispatchConditionImpl:'''
			«BC.dealWithDispatchConditionImpl.toString.clearspace»
			'''
			default:'''
			default «BC.class» at BaAnnexTemplate.xtend line 120
			'''
		}»
		«ELSE»
		true
		«ENDIF»	
	'''	
	def static dealWithDispatchConditionImpl(DispatchConditionImpl dis)'''
		«val c1=dis.dispatchTriggerCondition as DispatchTriggerLogicalExpressionImpl»
		«c1.dispatchConjunctions.get(0).dispatchTriggers.get(0).elementRoot.name»==true
	'''
		
	def static getInitialStateEx(BehaviorAnnexImpl ba)'''
	enum State initialState = «ba.getInitialState.name»;
	'''	
	
	
	def static getFinalStateEx(BehaviorAnnexImpl ba)'''
	enum State finalState = «ba.getFinalStateName»;
	'''	
	
	
	def static getFinalStateName(BehaviorAnnexImpl ba)'''
	«FOR  bs :ba.states»
	«IF bs.isFinal»
		«bs.name»
	«ENDIF»
	«ENDFOR»
	'''	
		

	def static conditionTemplate(Relation  relation)'''
		«relation.firstExpression.terms.get(0).getFactors.get(0).getFirstValue.translateValue1.toString»
		«IF relation.secondExpression!==null»
			«relation.relationalOperator.dealWithRelationalOperator» «relation.secondExpression.terms.get(0).getFactors.get(0).getFirstValue.translateValue1.toString»
		«ENDIF»		
	'''
	def static dealWithRelationalOperator(RelationalOperator o)'''
		«IF o==RelationalOperator.EQUAL»
		==
		«ELSE»
		«o»
		«ENDIF»
	'''
	
	def static actionblockTemplate(BehaviorActionBlock bb)'''
		«IF bb!=null»
			«FOR bb_child:bb.children»
			«switch bb_child{
				BehaviorActionSequenceImpl:'''
				«FOR action :bb_child.getActions»
				«action.actionTemplate»
				«ENDFOR»
				'''
				BehaviorTimeImpl:'''
				taskDelay(«bb_child.getIntegerValue»); //«bb_child.getUnit.name» 
				'''
				PortSendActionImpl:'''
				«bb_child.actionTemplate»
				'''
				AssignmentActionImpl:'''
				«bb_child.actionTemplate»
				'''
				SubprogramCallActionImpl:'''
				«bb_child.actionTemplate»
				'''
				PortDequeueActionImpl:'''
				«bb_child.actionTemplate»
				'''
				default:'''
				class: «bb_child.class»'s dealer is default in BaAnnexTemplate,line 193
				'''
			}»
			«ENDFOR»
		«ENDIF»	
		«IF bb==null»
		printf("Without actionBlock");
		«ENDIF»			
	'''
	
	def static targetTemplate(Target target){
	switch target{
		BehaviorVariableHolderImpl:'''
		«target.getBehaviorVariable.name»
		'''	
		DataSubcomponentHolderImpl:'''
		«target.getDataSubcomponent.name»
		'''
		DataAccessHolderImpl:'''
		«target.dataAccess.name»
		'''
		DataComponentReferenceImpl:'''
		«target.translateDataComponentReference»
		'''
		ParameterHolderImpl:'''
		«target.translateValue1»
		'''
		default:'''
			target_template has no strategy for «target.class»
		'''
	}
	}
	
	
	def static actionTemplate(BehaviorAction baAction)'''
	
	//TODO
	«switch baAction{
			AssignmentActionImpl:'''
				«FOR Relation relation :baAction.getValueExpression.getRelations»
				«baAction.getTarget.targetTemplate.toString.clearspace» = «relation.relationTemplate.toString.clearspace»;   //:=
				«ENDFOR»	
			'''
			PortDequeueActionImpl:'''
				«baAction.getTarget.targetTemplate.toString.clearspace» = «baAction.getPort.getPort().name.clearspace» ;   //?=
			'''
			PortSendActionImpl:'''
				«FOR relation:baAction.getValueExpression.getRelations»
				«baAction.getPort.getPort().name.convertNo2Low» = «relation.relationTemplate.toString.clearspace»;   //!=
				«relation.relationTemplate2»
				«ENDFOR»
			'''
			SubprogramCallActionImpl:'''
				«baAction.subprogram.element.name»(«baAction.parameterLabels.parameterTemplate.toString.clearspace.removeLastChar»);
			'''
			TimedActionImpl:'''
				taskDelay(«baAction.lowerTime»);
			'''
			default:'''
				baAction_template has no strategy for «baAction.class»
				'''
			}»
	'''
	def static parameterTemplate(EList<ParameterLabel> paras)'''
	«FOR para :paras»
	«switch para{
		DataSubcomponentHolder:'''
			«para.element.name»,
		'''
		ValueExpressionImpl:'''
			«para.translateValue1»,
		'''
		BehaviorVariableHolderImpl:'''
			«para.getBehaviorVariable.name»
		'''
		default:'''
			BaAnnexTemplate 272 default «para»
		'''
	}
	
	»
	«ENDFOR»
	
	
	'''
	def static relationTemplate(Relation relation)'''
	«switch relation{	
		RelationImpl:'''
		«relation.firstExpression.terms.get(0).getFactors.get(0).getFirstValue.translateValue1»
		'''		

		default:'''
		relation_template has no strategy for «relation.class»
		'''
	}»
	'''
	
	
	def static relationTemplate2(Relation relation)'''
	«switch relation{	
		RelationImpl:'''
		«IF relation.secondExpression!=null»
		«relation.secondExpression.terms.get(0).getFactors.get(0).getFirstValue.translateValue1»
		«ENDIF»
		'''		
		default:'''
		relation_template2 has no strategy for «relation.class»
		'''
	}»
	'''
	
	def static translateValue1(Value value)'''
		«switch value{
			DataComponentReferenceImpl:'''
			«value.translateDataComponentReference»
			'''
			BehaviorVariableHolderImpl:'''
			«value.getBehaviorVariable.name»
			'''
			BehaviorIntegerLiteralImpl:'''
			«value.getValue»
			'''
			BehaviorBooleanLiteralImpl:'''
			«value.getValue()»
			'''	
			BehaviorRealLiteralImpl:'''
			«value.getValue()»
			'''
			ValueExpressionImpl:'''
			«value.conditionsTemplate»
			'''
			DataAccessHolderImpl:'''
				«value.dataAccess.name»
			'''
			BehaviorStringLiteralImpl:'''
				"«value.value»"
			'''
			ParameterHolderImpl:'''
				«value.parameter.name»
			'''
			DataSubcomponentHolderImpl:'''
				«value.dataSubcomponent.name.convertNo2Low»
			'''
			default:'''
			BaAnnexTemplate.translateValue1 has no idea about «value»   third-4-11-lwx
			'''
		}»
	'''

//	def static translateDataComponentReference(DataComponentReferenceImpl value)'''
//				«var flag=true»
//				«var flag1=false»
//				«FOR DataHolder d:value.data»
//				«IF true==flag»
//				«switch d{
//						BehaviorVariableHolderImpl:'''
//						«d.getBehaviorVariable.name»'''
//						DataSubcomponentHolderImpl:'''
//						«d.getDataSubcomponent.name»'''
//						DataAccessHolderImpl:'''
//						«d.dataAccess.name»
//						'''
//						default:'''
//						BaAnnexTemplate.translateValue1 has no idea about «d»  first-4-11-lwx'''
//				}»
//				«ELSE»
//				.
//				«switch d{
//						BehaviorVariableHolderImpl:'''
//						«d.getBehaviorVariable.name»'''						
//						DataSubcomponentHolderImpl:'''
//						«d.getDataSubcomponent.name»'''					
//						default:'''
//						BaAnnexTemplate.translateValue1 has no idea about «d»  second-4-11-lwx
//						'''
//				}»
//				«ENDIF»
//				«flag=false»
//				«ENDFOR»
//	'''
	
	def static translateDataComponentReference(DataComponentReferenceImpl value){
			var flag=true
			var v_name=""
			for(DataHolder d:value.data) 
				if(true==flag){
					flag=false
					switch d{
							BehaviorVariableHolderImpl:
								v_name+=d.getBehaviorVariable.name
							DataSubcomponentHolderImpl:
								v_name+=d.getDataSubcomponent.name
							DataAccessHolderImpl:
								v_name+=d.dataAccess.name
							ParameterHolderImpl:
								v_name+=d.parameter.name
							default:
								v_name="BaAnnexTemplate.translateDataComponentReference has no idea about"+d+"first-4-11-lwx"
					}
				}
				else{
					switch d{
							BehaviorVariableHolderImpl:
								v_name+="."+d.getBehaviorVariable.name				
							DataSubcomponentHolderImpl:
								v_name+="."+d.getDataSubcomponent.name		
							ParameterHolderImpl:
								v_name+="."+d.parameter.name		
							default:
								v_name="BaAnnexTemplate.translateDataComponentReference 2 has no idea about"+d+"second-4-11-lwx"
					}
				}
				return v_name
}
	
	
	def static translateLogOperator(LogicalOperator logOperator)'''
	«switch logOperator.getValue{
		case 0:'''
		~
		'''
		case 1:'''
		&&
		'''
		case 2:'''
		||
		'''
		case 3:'''
		XOR
		'''
	}»
	'''
	
	
}